package com.troila.rpc;

import com.troila.config.RpcConfig;
import io.grpc.Server;
import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class RpcServer {

    private DataRpcService service;

    private RpcConfig config;

    private MetaDataInterceptor interceptor;

    @Autowired
    public void setService(DataRpcService service) {
        this.service = service;
    }

    @Autowired
    public void setConfig(RpcConfig config) {
        this.config = config;
    }

    @Autowired
    public void setInterceptor(MetaDataInterceptor interceptor) {
        this.interceptor = interceptor;
    }

    public void start() throws IOException, InterruptedException {
        Server server = NettyServerBuilder.forPort(config.getRpc().getPort())
                .keepAliveTime(config.getRpc().getKeepAliveTime(), TimeUnit.SECONDS)
                .keepAliveTimeout(config.getRpc().getKeepAliveTimeout(), TimeUnit.SECONDS)
                .permitKeepAliveWithoutCalls(config.getRpc().isPermitKeepAliveWithoutCalls())
                .maxConnectionIdle(config.getRpc().getMaxClientIdleTimeout(), TimeUnit.MILLISECONDS)
                .addService(service)
                .intercept(interceptor)
                .build()
                .start();
        log.info("rpc server started on port(s) {}", config.getRpc().getPort());
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            log.info("rpc server is shutting down.");
            if (Objects.isNull(server)) {
                server.shutdown();
            }
        }));
        server.awaitTermination();
    }

}
